package frame.options.virtual;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.io.File;
import java.util.ArrayList;
import java.util.List;

import javax.swing.ImageIcon;
import javax.swing.JFileChooser;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;

import jxl.LabelCell;
import jxl.NumberCell;
import jxl.Sheet;
import jxl.Workbook;
import jxl.write.WritableCellFormat;
import jxl.write.WritableFont;
import model.components.links.link.VirtualLink;
import model.components.networks.virtual.VirtualNetwork;
import model.components.nodes.node.Node;
import model.components.nodes.node.virtual.VirtualMachine;
import model.components.nodes.node.virtual.VirtualNode;
import model.components.nodes.node.virtual.VirtualRouter;
import model.components.nodes.node.virtual.VirtualSwitch;
import frame.SimulatorFrame;
import frame.networks.tables.virtual.VirtualTableModel;

@SuppressWarnings("serial")
public class OpenVirtualMenuItem extends JMenuItem implements ActionListener
{
	private SimulatorFrame simulatorFrame;
	public SimulatorFrame getFrame(){ return simulatorFrame; }
	public void setFrame( SimulatorFrame simulatorFrame ){ this.simulatorFrame = simulatorFrame; }

	private JFileChooser fileChooser;
	public JFileChooser getFileChooser(){ return fileChooser; }
    public void setFileChooser( JFileChooser fileChooser ){ this.fileChooser = fileChooser; }
	
	public OpenVirtualMenuItem( SimulatorFrame simulatorFrame )
	{
		this.setFrame( simulatorFrame );
		
		this.setText( "Open" );
		this.setMnemonic( KeyEvent.VK_O );
		this.setIcon( new ImageIcon( this.getClass().getResource( "/icons/open.png" ) ) );
		this.setFileChooser( new JFileChooser() );
		this.addActionListener( this );
	}
	
	@Override
	public void actionPerformed( ActionEvent actionEvent )
	{
		this.getFrame().getNetworksPanel().getNetworksTablesTabbedPane().setSelectedIndex( 1 );
		
		if( this.getFileChooser().showOpenDialog( this ) == JFileChooser.APPROVE_OPTION )
		{
			try
			{
				List< VirtualNetwork > virtualNetworks = this.openVirtualNetworks( this.getFileChooser().getSelectedFile() );
			
				//this.getFrame().getSimulator().getVirtualNetworks().clear();
				this.getFrame().getNetworksPanel().getVirtualNetworksVisualizationViewersTabbedPane().removeAll();
				this.getFrame().getNetworksPanel().getNetworksTablesTabbedPane().getVirtualNetworksTable().removeAll();
				
				this.getFrame().getSimulator().setInitVirtualNetworks( virtualNetworks );
				this.getFrame().getSimulator().reset();
				
				for( VirtualNetwork virtualNetwork: virtualNetworks )
				{
					//this.getFrame().getSimulator().getVirtualNetworks().add( virtualNetwork );
					this.getFrame().getNetworksPanel().getVirtualNetworksVisualizationViewersTabbedPane().addVirtualNetworkTab( virtualNetwork );
					( (VirtualTableModel) this.getFrame().getNetworksPanel().getNetworksTablesTabbedPane().getVirtualNetworksTable().getModel() ).addRow( new Object[]{ virtualNetwork.getName(), virtualNetwork.getStartingDate(), virtualNetwork.getEndingDate(), virtualNetwork.getState() } );
				}
				
				( (VirtualTableModel) getFrame().getNetworksPanel().getNetworksTablesTabbedPane().getVirtualNetworksTable().getModel() ).refresh();
			}
			catch( Exception exception )
			{
				JOptionPane.showMessageDialog( this.getFrame().getNetworksPanel(), "Incorrect file", "Filer error", 1 );
			}
		}
	}
	
	public List< VirtualNetwork > openVirtualNetworks( File file ) throws Exception
	{
		List< VirtualNetwork > virtualNetworks = new ArrayList< VirtualNetwork >();
		
		Workbook workbook = Workbook.getWorkbook( file );
		
		WritableFont writableFontBold = new WritableFont( WritableFont.ARIAL, 10, WritableFont.BOLD );
		WritableCellFormat writableCellFormatBold = new WritableCellFormat( writableFontBold );
		writableCellFormatBold.setWrap( true );
							
		WritableFont writableFontNoBold = new WritableFont( WritableFont.ARIAL, 10, WritableFont.NO_BOLD );
		WritableCellFormat writableCellFormatNoBold = new WritableCellFormat( writableFontNoBold );
		writableCellFormatNoBold.setWrap( true );
				
		String sheetNames[] = workbook.getSheetNames();
		int sheetCount = 0;
		
		while( sheetCount < sheetNames.length )
		{
			Sheet sheet = workbook.getSheet( sheetNames[ sheetCount++ ] );
			
			int columnCount = 0;
			int rowCount = 2;
			String namePrefix = sheet.getCell( columnCount++, rowCount ).getContents();
			int networkNumber = Integer.parseInt( sheet.getCell( columnCount++, rowCount ).getContents() );
			int startingDate = Integer.parseInt( sheet.getCell( columnCount++, rowCount ).getContents() );
			int endingDate = Integer.parseInt( sheet.getCell( columnCount++, rowCount ).getContents() );
			
			VirtualNetwork virtualNetwork = new VirtualNetwork( namePrefix, networkNumber, startingDate, endingDate );
			
			List< Node > nodes = new ArrayList< Node >();
			
			columnCount = 0;	
			rowCount = 5;
			
			while( !sheet.getCell( columnCount, rowCount ).getContents().equals( "LINKS" ) )
			{
				String networkName = ( (LabelCell) sheet.getCell( columnCount++, rowCount ) ).getString();
				int number = (int)( (NumberCell) sheet.getCell( columnCount++, rowCount ) ).getValue();
				String type = ( (LabelCell) sheet.getCell( columnCount++, rowCount ) ).getString();
				String os = ( (LabelCell) sheet.getCell( columnCount++, rowCount ) ).getString();
				int cpu = (int)( (NumberCell) sheet.getCell( columnCount++, rowCount ) ).getValue();
				int ram = (int)( (NumberCell) sheet.getCell( columnCount++, rowCount ) ).getValue();
				int storage  = (int)( (NumberCell) sheet.getCell( columnCount++, rowCount ) ).getValue();
				columnCount = 0;
				rowCount++;
									
				VirtualNode virtualNode = null;
				
				if( type.equals( Node.ROUTER_TYPE ) )
					virtualNode = new VirtualRouter( networkName, startingDate, endingDate, number, os, cpu, ram );
				
				else if( type.equals( Node.SWITCH_TYPE ) )
					virtualNode = new VirtualSwitch( networkName, startingDate, endingDate, number, os, cpu, ram );
				
				else if( type.equals( Node.SERVER_TYPE ) )
					virtualNode = new VirtualMachine( networkName, startingDate, endingDate, number, os, cpu, ram, storage );
				
				virtualNode.setInitialNumber( number );
				nodes.add( virtualNode );
			}
			
			columnCount = 0;
			rowCount += 2;
			
			while( !sheet.getCell( columnCount, rowCount ).getContents().equals( "END" ) )
			{
				String networkName = sheet.getCell( columnCount++, rowCount ).getContents();
				int number = Integer.parseInt( sheet.getCell( columnCount++, rowCount ).getContents() );
				String firstNodeName = sheet.getCell( columnCount++, rowCount ).getContents();
				String secondNodeName = sheet.getCell( columnCount++, rowCount ).getContents();
				int bw = Integer.parseInt( sheet.getCell( columnCount++, rowCount ).getContents() );
				columnCount = 0;
				rowCount++;
				
				VirtualLink virtualLink = new VirtualLink( networkName, startingDate, endingDate, number, bw );
				Node firstNode = this.getNodeByName( firstNodeName, nodes );
				Node secondNode = this.getNodeByName( secondNodeName, nodes );
				
				virtualLink.setInitialNumber( number );
				virtualNetwork.addLinkAndNodes( virtualLink, firstNode, secondNode );
			}
			
			virtualNetworks.add( virtualNetwork );
		}
		
		workbook.close();
				
		return virtualNetworks;
	}
	
	private Node getNodeByName( String nodeName, List< Node > nodes )
	{
		for( Node node: nodes )
			if( node.getName().equals( nodeName ) )
				return node;
		
		return null;
	}

}
